from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

from business.models import LoadParams, EnergyPurchase, EnergySale2C, EnergySale2B, WindLoad, LightLoad, DesignPlan, \
    ARS, ICE, GasTurbine, AR, WindPower, PVP, GroundPump, AirPump, GasBoiler, ElectricBoiler, ERU, IceTank, Buttery, \
    OptConfig
from users.models import Users


def page_n(data, page, limit=8):  # 分页
    paginator = Paginator(data, limit)
    try:
        data = paginator.page(page)
    except PageNotAnInteger:
        data = paginator.page(1)
    except EmptyPage:
        data = paginator.page(paginator.num_pages)
    return data


def safer(data, return_value=None):
    """
    数据安全优化
    :param data:传入的数据
    :param return_value:自定义为空时的返回值
    :return:如果传入结果不为空，则直接返回，否则返回一个非空的结果，非空结果可以自定义
    """
    return data if data else (return_value if return_value else 0)


def clean_temp_table(target_id):
    if target_id:
        LoadParams.objects.filter(design_id=target_id).delete()
        EnergyPurchase.objects.filter(design_id=target_id).delete()
        EnergySale2C.objects.filter(design_id=target_id).delete()
        EnergySale2B.objects.filter(design_id=target_id).delete()
        WindLoad.objects.filter(design_id=target_id).delete()
        LightLoad.objects.filter(design_id=target_id).delete()
    else:
        pass


def save_params(account, params, d_id):
    """
    该方法用于解析用户传入的配置参数，并保存至数据库中
    :param account:
    :param params:
    :param d_id:
    :return:
    """
    dp = DesignPlan()
    dp.design_id = d_id
    dp.d_name = params['name']
    dp.d_desc = params['desc']
    dp.belongs = Users.objects.get(account=account)
    dp.model_which = int(params['model']['which'])
    dp.opt_target = int(params['opt_target'])
    dp.summer_day = params['summer_day']
    dp.winter_day = params['winter_day']
    dp.model_buy_gas = bool(params['model']['buy_gas'])
    dp.gas_max_power = float(params["model"]["gas_max"]) if dp.model_buy_gas else 0
    dp.model_buy_heat = bool(params['model']['buy_heat'])
    dp.heat_max_power = float(params["model"]["heat_max"]) if dp.model_buy_heat else 0
    dp.cchp_is_selected = bool(params['CCHP']['is_selected'])

    max_power = params['CCHP']['parameter']['max_power']
    min_power = params['CCHP']['parameter']['min_power']
    dp.cchp_max_power = float(max_power) if dp.cchp_is_selected and max_power else 0  # 非空判断
    dp.cchp_min_power = float(min_power) if dp.cchp_is_selected and max_power else 0  # 非空判断

    dp.ars_is_selected = bool(params['CCHP']['ARS']['is_selected'])

    if dp.ars_is_selected:
        which_ar = params['CCHP']['ARS']['which']
        dp.ars_which = which_ar if which_ar else ARS.objects.get(is_default=True).model_name
    else:
        dp.ars_which = ''

    dp.ice_is_selected = bool(params['CCHP']['ICE']['is_selected'])

    if dp.ice_is_selected:
        which_ice = params['CCHP']['ICE']['which']
        dp.ice_which = which_ice if dp.ice_which else ICE.objects.get(is_default=True).model_name
    else:
        dp.ice_which = ''

    dp.gt_is_selected = bool(params['CCHP']['gt']['is_selected'])

    if dp.gt_is_selected:
        which_gt = params['CCHP']['gt']['which']
        dp.gt_which = which_gt if dp.gt_which else GasTurbine.objects.get(is_default=True).model_name
    else:
        dp.gt_which = ''

    dp.ar_is_selected = bool(params['ar']['is_selected'])

    if dp.ar_is_selected:
        which_ar = params['ar']['which']
        dp.ar_max_power = float(params['ar']["max_power"]) if float(params['ar']["max_power"]) else 0
        dp.ar_min_power = float(params['ar']["min_power"]) if float(params['ar']["min_power"]) else 0
        dp.ar_which = which_ar if which_ar else AR.objects.get(is_default=True).model_name
    else:
        dp.ar_which = ''
        dp.ar_max_power = 0
        dp.ar_min_power = 0

    dp.re_is_selected = bool(params['re']['is_selected'])
    dp.wind_is_selected = bool(params['re']['wind']['is_selected'])
    if dp.wind_is_selected:
        which_wind = params['re']['wind']['which']
        count_max = params['re']['wind']['wind_count_max']
        count_min = params['re']['wind']['wind_count_min']
        dp.wind_count_max = count_max if count_max else 0
        dp.wind_count_min = count_min if count_min else 0
        dp.wind_which = which_wind if which_wind else WindPower.objects.get(is_default=True).model_name
    else:
        dp.wind_which = ''
        dp.pv_count_max = 0
        dp.pv_count_min = 0

    dp.solar_is_selected = bool(params['re']['solar']['is_selected'])
    if dp.solar_is_selected:
        which_solar = params['re']['solar']['which']
        count_max = params['re']['solar']['pv_count_max']
        count_min = params['re']['solar']['pv_count_min']
        dp.pv_count_max = count_max if count_max else 0
        dp.pv_count_min = count_min if count_min else 0
        dp.solar_which = which_solar if which_solar else PVP.objects.get(is_default=True).model_name
    else:
        dp.solar_which = ''
        dp.pv_count_max = 0
        dp.pv_count_min = 0

    dp.hp_is_selected = bool(params['hp']['is_selected'])
    dp.gp_is_selected = bool(params['hp']['gp']['is_selected'])
    if dp.gp_is_selected:
        which_gp = params['hp']['gp']['which']
        dp.gp_which = which_gp if which_gp else GroundPump.objects.get(is_default=True).model_name
    else:
        dp.gp_which = ''
    max_power = params['hp']['gp']['parameter']['max_power']
    min_power = params['hp']['gp']['parameter']['min_power']
    dp.gp_max_power = float(max_power) if max_power and dp.gp_is_selected else 0
    dp.gp_min_power = float(min_power) if max_power and dp.gp_is_selected else 0
    dp.ap_is_selected = bool(params['hp']['ap']['is_selected'])
    if dp.ap_is_selected:
        which_ap = params['hp']['ap']['which']
        dp.ap_which = which_ap if which_ap else AirPump.objects.get(is_default=True).model_name
    else:
        dp.ap_which = ''

    max_power = params['hp']['ap']['parameter']['max_power']
    min_power = params['hp']['ap']['parameter']['min_power']
    dp.ap_max_power = float(max_power) if max_power and dp.ap_is_selected else 0
    dp.ap_min_power = float(min_power) if min_power and dp.ap_is_selected else 0

    dp.boiler_is_selected = bool(params['boiler']['is_selected'])
    dp.gb_is_selected = bool(params['boiler']['gb']['is_selected'])
    if dp.gb_is_selected:
        which_gb = params['boiler']['gb']['which']
        dp.gb_which = which_gb if which_gb else GasBoiler.objects.get(is_default=True).model_name
        dp.gb_max_power = params['boiler']['gb']['parameter']['max_power'] if params['boiler']['gb']['parameter'][
            'max_power'] else 0
        dp.gb_min_power = params['boiler']['gb']['parameter']['min_power'] if params['boiler']['gb']['parameter'][
            'min_power'] else 0
    else:
        dp.gb_which = ''
        dp.gb_max_power = 0
        dp.gb_min_power = 0

    dp.eb_is_selected = bool(params['boiler']['eb']['is_selected'])

    if dp.eb_is_selected:
        which_eb = params['boiler']['eb']['which']
        dp.eb_which = which_eb if which_eb else ElectricBoiler.objects.get(is_default=True).model_name
        dp.eb_max_power = params['boiler']['eb']['parameter']['max_power'] if params['boiler']['eb']['parameter'][
            'max_power'] else 0
        dp.eb_min_power = params['boiler']['eb']['parameter']['min_power'] if params['boiler']['eb']['parameter'][
            'min_power'] else 0
    else:
        dp.eb_which = ''
        dp.eb_max_power = 0
        dp.eb_min_power = 0

    dp.ese_is_selected = bool(params['ese']['is_selected'])
    dp.ice_storage_is_selected = bool(params['ese']['ice_storage']['is_selected'])
    max_cap = params['ese']['ice_storage']['parameter']['max_capacity']
    min_cap = params['ese']['ice_storage']['parameter']['min_capacity']
    dp.ice_storage_max_capacity = max_cap if dp.ice_storage_is_selected and max_cap else 0
    dp.ice_storage_min_capacity = min_cap if dp.ice_storage_is_selected and min_cap else 0
    max_cap = params['ese']['ice_storage']['parameter']['max_power']
    min_cap = params['ese']['ice_storage']['parameter']['min_power']
    dp.ice_storage_max_power_ch = max_cap if dp.ice_storage_is_selected and max_cap else 0
    dp.ice_storage_min_power_ch = min_cap if dp.ice_storage_is_selected and min_cap else 0

    max_power_dis = params['ese']['ice_storage']['parameter']['ice_storage_max_powerdis']
    min_power_dis = params['ese']['ice_storage']['parameter']['ice_storage_min_powerdis']

    dp.ice_storage_max_power_dis = max_power_dis if dp.ice_storage_is_selected and max_power_dis else 0
    dp.ice_storage_min_power_dis = min_power_dis if dp.ice_storage_is_selected and min_power_dis else 0

    dp.cu_is_selected = bool(params['ese']['ice_storage']['cu']['is_selected'])
    if dp.cu_is_selected:
        which_cu = params['ese']['ice_storage']['cu']['which']
        dp.cu_which = which_cu if which_cu else ERU.objects.get(is_default=True).model_name
    else:
        dp.cu_which = ''
    dp.it_is_selected = bool(params['ese']['ice_storage']['it']['is_selected'])
    if dp.it_is_selected:
        which_it = params['ese']['ice_storage']['it']['which']
        dp.it_which = which_it if which_it else IceTank.objects.get(is_default=True).model_name
    else:
        dp.it_which = ''
    dp.heat_storage_is_selected = bool(params['ese']['heat_storage']['is_selected'])

    cap = params['ese']['heat_storage']['parameter']['max_capacity']
    cap_min = params['ese']['heat_storage']['parameter']['min_capacity']
    dp.heat_storage_max_capacity = float(cap) if dp.heat_storage_is_selected and cap else 0
    dp.heat_storage_min_capacity = float(cap_min) if dp.heat_storage_is_selected and cap_min else 0

    max_powerch = params['ese']['heat_storage']['parameter']['max_powerch']
    max_powerdis = params['ese']['heat_storage']['parameter']['max_powerdis']
    dp.heat_storage_max_powerch = float(max_powerch) if max_powerch else 0
    dp.heat_storage_max_powerdis = float(max_powerdis) if max_powerdis else 0

    ch = params['ese']['heat_storage']['parameter']['min_powerch']
    dis = params['ese']['heat_storage']['parameter']['min_powerdis']
    dp.heat_storage_min_powerch = float(ch) if dp.heat_storage_is_selected and ch else 0
    dp.heat_storage_min_powerdis = float(dis) if dp.heat_storage_is_selected and dis else 0

    eff = params['ese']['heat_storage']['parameter']['efficiency']
    dp.heat_storage_efficiency = float(eff) if dp.heat_storage_is_selected and eff else 0
    dp.ele_storage_is_selected = bool(params['ese']['ele_storage']['is_selected'])
    cap = params['ese']['ele_storage']['parameter']['max_capacity']
    cap_min = params['ese']['ele_storage']['parameter']['min_capacity']
    dp.ele_storage_max_capacity = float(cap) if dp.ele_storage_is_selected and cap else 0
    dp.ele_storage_min_capacity = float(cap_min) if dp.ele_storage_is_selected and cap_min else 0
    max_powerch = params['ese']['ele_storage']['parameter']['max_charge']
    min_powerch = params['ese']['ele_storage']['parameter']['min_charge']
    heat_storage_investment = params['ese']['heat_storage']['parameter']['investment']

    dp.ele_storage_max_powerch = float(max_powerch) if max_powerch else 0
    dp.ele_storage_max_powerdis = float(min_powerch) if min_powerch else 0
    dp.heat_storage_investment = float(heat_storage_investment) if heat_storage_investment else 0

    dp.battery_is_selected = bool(params['ese']['ele_storage']['battery']['is_selected'])
    if dp.battery_is_selected:
        which_battery = params['ese']['ele_storage']['battery']['which']
        dp.battery_which = which_battery if which_battery else Buttery.objects.get(is_default=True).model_name
    else:
        dp.battery_which = ''

    dp.pop_size = float(params['algParams']['pop_size'])
    dp.c1 = float(params['algParams']['c1'])
    dp.c2 = float(params['algParams']['c2'])
    dp.inertia_weight = float(params['algParams']['weight'])
    dp.iter_max_num = float(params['algParams']['ite_count'])
    dp.fly_speed = float(params['algParams']['percentage'])
    dp.residual = float(params['algParams']['residual'])

    dp.save()


def save_opt_params(account, params, opt_id):
    config = OptConfig()
    config.opt_id = opt_id
    config.opt_name = params['baseInfo']['name']
    config.opt_desc = params['baseInfo']['desc']
    config.predict_date = params['baseInfo']['predictDate']
    config.opt_target = int(params['optTarget'])
    config.belongs = Users.objects.get(account=account)
    config.model_which = params['modeInfo']['which']
    config.power_ensure_rate = params['modeInfo']['power_ensure_rate']
    config.heat_ensure_rate = params['modeInfo']['heat_ensure_rate']
    config.cold_ensure_rate = params['modeInfo']['cold_ensure_rate']
    config.model_buy_gas = bool(params['modeInfo']['buy_gas'])
    config.model_buy_heat = bool(params['modeInfo']['buy_heat'])
    config.gas_max_output = params['modeInfo']['gas_max']
    config.heat_max_output = params['modeInfo']['heat_max']
    config.cchp_is_selected = params['deviceInfo']['CCHP']['is_selected']
    config.ars_is_selected = params['deviceInfo']['CCHP']['ARS']['is_selected']
    config.ars_which = params['deviceInfo']['CCHP']['ARS']['which']
    config.ars_count = params['deviceInfo']['CCHP']['ARS']['count']
    config.ice_is_selected = params['deviceInfo']['CCHP']['ICE']['is_selected']
    config.ice_which = params['deviceInfo']['CCHP']['ICE']['which']
    config.ice_count = params['deviceInfo']['CCHP']['ICE']['count']
    config.gt_is_selected = params['deviceInfo']['CCHP']['gt']['is_selected']
    config.gt_which = params['deviceInfo']['CCHP']['gt']['which']
    config.gt_count = params['deviceInfo']['CCHP']['gt']['count']
    config.ar_is_selected = params['deviceInfo']['ar']['is_selected']
    config.ar_which = params['deviceInfo']['ar']['which']
    config.ar_count = params['deviceInfo']['ar']['count']
    config.re_is_selected = params['deviceInfo']['re']['is_selected']
    config.wind_is_selected = bool(params['deviceInfo']['re']['wind']['is_selected'])
    config.wind_which = params['deviceInfo']['re']['wind']['which']
    config.wind_count = params['deviceInfo']['re']['wind']['count']

    config.solar_is_selected = bool(params['deviceInfo']['re']['solar']['is_selected'])
    config.solar_which = params['deviceInfo']['re']['solar']['which']
    config.solar_count = params['deviceInfo']['re']['solar']['count']

    config.hp_is_selected = params['deviceInfo']['hp']['is_selected']
    config.gp_is_selected = params['deviceInfo']['hp']['gp']['is_selected']
    config.gp_which = params['deviceInfo']['hp']['gp']['which']
    config.gp_count = params['deviceInfo']['hp']['gp']['count']

    config.ap_is_selected = params['deviceInfo']['hp']['ap']['is_selected']
    config.ap_which = params['deviceInfo']['hp']['ap']['which']
    config.ap_count = params['deviceInfo']['hp']['ap']['count']

    config.boiler_is_selected = params['deviceInfo']['boiler']['is_selected']
    config.gb_is_selected = params['deviceInfo']['boiler']['gb']['is_selected']
    config.gb_which = params['deviceInfo']['boiler']['gb']['which']
    config.gb_count = params['deviceInfo']['boiler']['gb']['count']

    config.eb_is_selected = params['deviceInfo']['boiler']['eb']['is_selected']
    config.eb_which = params['deviceInfo']['boiler']['eb']['which']
    config.eb_count = params['deviceInfo']['boiler']['eb']['count']

    config.ese_is_selected = params['deviceInfo']['ese']['is_selected']
    config.ice_storage_is_selected = params['deviceInfo']['ese']['ice_storage']['is_selected']

    config.cu_is_selected = params['deviceInfo']['ese']['ice_storage']['cu']['is_selected']
    config.cu_which = params['deviceInfo']['ese']['ice_storage']['cu']['which']
    config.cu_count = params['deviceInfo']['ese']['ice_storage']['cu']['count']

    config.it_is_selected = params['deviceInfo']['ese']['ice_storage']['it']['is_selected']
    config.it_which = params['deviceInfo']['ese']['ice_storage']['it']['which']
    config.it_count = params['deviceInfo']['ese']['ice_storage']['it']['count']

    config.heat_storage_is_selected = params['deviceInfo']['ese']['heat_storage']['is_selected']

    efficiency = params['deviceInfo']['ese']['heat_storage']['parameter']['efficiency']
    max_capacity = params['deviceInfo']['ese']['heat_storage']['parameter']['max_capacity']
    max_powerch = params['deviceInfo']['ese']['heat_storage']['parameter']['max_powerch']
    max_powerdis = params['deviceInfo']['ese']['heat_storage']['parameter']['max_powerdis']

    config.heat_storage_efficiency = float(efficiency) if efficiency else 0
    config.heat_storage_max_capacity = float(max_capacity) if max_capacity else 0
    config.heat_storage_max_powerch = float(max_powerch) if max_powerch else 0
    config.heat_storage_max_powerdis = float(max_powerdis) if max_powerdis else 0

    config.ele_storage_is_selected = params['deviceInfo']['ese']['ele_storage']['is_selected']
    config.battery_is_selected = params['deviceInfo']['ese']['ele_storage']['battery']['is_selected']
    config.battery_which = params['deviceInfo']['ese']['ele_storage']['battery']['which']
    config.battery_count = params['deviceInfo']['ese']['ele_storage']['battery']['count']
    config.save()


def make_menu(is_admin):
    if is_admin:
        menu = [
            {"path": "/historyList", "icon": "el-icon-pie-chart", "title": "集成优化", "children": []},
            {"path": "/optCal", "icon": "el-icon-magic-stick", "title": "监控管理", "children": []},
            {"path": "/equipment", "icon": "el-icon-monitor", "title": "设备维护", "children": [
                {"path": "/equipment/ice", "title": "内燃机"},
                {"path": "/equipment/gb", "title": "燃气锅炉"},
                {"path": "/equipment/eb", "title": "电锅炉"},
                {"path": "/equipment/ar", "title": "直燃型制冷机"},
                {"path": "/equipment/iceTank", "title": "蓄冰槽"},
                {"path": "/equipment/eru", "title": "电制冷机组"},
                {"path": "/equipment/airPump", "title": "风冷热泵"},
                {"path": "/equipment/gp", "title": "地源热泵"},
                {"path": "/equipment/gt", "title": "燃气轮机"},
                {"path": "/equipment/wp", "title": "风机"},
                {"path": "/equipment/pvp", "title": "光伏板"},
                {"path": "/equipment/ars", "title": "烟气热水机"},
                {"path": "/equipment/buttery", "title": "蓄电池"},
            ]},
            {"path": "/ecoEval", "icon": "el-icon-setting", "title": "经评参数", "children": []},
            {"path": "/userManager", "icon": "el-icon-user", "title": "用户管理", "children": []},
        ]
    else:
        menu = [
            {"path": "/historyList", "icon": "el-icon-pie-chart", "title": "配置优化", "children": []},
            {"path": "/optCal", "icon": "el-icon-magic-stick", "title": "运行优化", "children": []},
        ]
    return menu


def get_device(table, config: DesignPlan, device_which: str, condition: str):
    if getattr(config, condition):
        target_obj = table.objects
        return target_obj.get(model_name=getattr(config, device_which)) if getattr(config,
                                                                                   device_which) else target_obj.get(
            is_default=True)
    else:
        return None
